home *** CD-ROM | disk | FTP | other *** search
- /*
- Little Smalltalk object definitions
- */
- # include "env.h"
- /*
- for objects the inst_var array is actually made as large as
- necessary (as large as the size field). since C does not do
- subscript bounds checking array indexing can be used
- */
-
- struct obj_struct {
- int ref_count;
- int size;
- struct class_struct *class;
- struct obj_struct *super_obj;
- struct obj_struct *inst_var[1];
- };
-
- /*
- for classes
- c_size = CLASSSIZE
-
- class_name and super_class should be SYMBOLs
- containing the names of the class and superclass,
- respectively.
-
- c_inst_vars should be an array of symbols, containing the
- names of the instance variables
-
- context size is the size of the context that should be
- created each time a message is sent to objects of this
- class.
-
- message_names should be an array of symbols, corresponding
- to the messages accepted by objects of this class.
-
- methods should be an array of arrays, each element being a
- two element array of bytecodes and literals.
- */
-
- struct class_struct {
- int c_ref_count;
- int c_size;
- struct obj_struct *class_name;
- struct obj_struct *super_class;
- struct obj_struct *file_name;
- struct obj_struct *c_inst_vars;
- int context_size;
- struct obj_struct *message_names;
- struct obj_struct *methods;
- int stack_max;
- };
-
- typedef struct class_struct class;
- typedef struct obj_struct object;
-
- /*
- objects with non-object value (classes, integers, etc) have a
- negative size field, the particular value being used to indicate
- the type of object (the class field cannot be used for this purpose
- since all classes, even those for built in objects, can be redefined)
-
- check_bltin is a macro that tests the size field for a particular
- value. it is used to define other macros, such as is_class, that
- test each particular type of object.
-
- The following classes are builtin
-
- Block
- ByteArray
- Char
- Class
- Float
- Integer
- Interpreter
- String
- Symbol
- */
-
- # define BLOCKSIZE -83
- # define BYTEARRAYSIZE -567
- # define CHARSIZE -33
- # define CLASSSIZE -3
- # define FILESIZE -5
- # define FLOATSIZE -31415
- # define INTEGERSIZE -17
- # define INTERPSIZE -15
- # define PROCSIZE -100
- # define STRINGSIZE -258
- # define SYMBOLSIZE -14
-
- # define is_bltin(x) (x && (((object *) x)->size < 0))
- # define check_bltin(obj, type) (obj && (((object *) obj)->size == type))
-
- # define is_block(x) check_bltin(x, BLOCKSIZE)
- # define is_bytearray(x) check_bltin(x, BYTEARRAYSIZE)
- # define is_character(x) check_bltin(x, CHARSIZE)
- # define is_class(x) check_bltin(x, CLASSSIZE)
- # define is_file(x) check_bltin(x, FILESIZE)
- # define is_float(x) check_bltin(x, FLOATSIZE)
- # define is_integer(x) check_bltin(x, INTEGERSIZE)
- # define is_interpreter(x) check_bltin(x, INTERPSIZE)
- # define is_process(p) check_bltin(p, PROCSIZE)
- # define is_string(x) check_bltin(x, STRINGSIZE)
- # define is_symbol(x) check_bltin(x, SYMBOLSIZE)
-
- /*
- mstruct is used (via casts) to store linked lists of structures of
- various types for memory saving and recovering
- */
-
- struct mem_struct {
- struct mem_struct *mlink;
- };
-
- typedef struct mem_struct mstruct;
-
- /*
- sassign assigns val to obj, which should not have a valid
- value in it already.
- assign decrements an existing val field first, then assigns.
- note this will not work for assign(x,x) if x ref count is 1.
- safeassign, although producing less efficient code, will work even
- in this case
- */
- # define sassign(obj, val) obj_inc((object *) (obj = val))
- # define assign(obj, val) {obj_dec((object *) obj); sassign(obj, val);}
- # define safeassign(obj, val) {obj_inc((object *) val); \
- obj_dec((object *) obj); obj = val; }
-
- /* structalloc calls alloc to allocate a block of memory
- for a structure and casts the returned
- pointer to the appropriate type */
- # define structalloc(type) (type *) o_alloc(sizeof(type))
-
- /*
- if INLINE is defined ( see env.h ) , inline code will be generated
- for object increments. inline code is generally faster, but
- larger than using subroutine calls for incs and decs
- */
-
- extern int n_incs, n_decs;
-
- # ifdef INLINE
-
- # define obj_inc(x) n_incs++, (x)->ref_count++
- extern object *_dx;
- # define obj_dec(x) {n_decs++; if (--((_dx=x)->ref_count) <= 0) ob_dec(_dx);}
-
- # endif
-
- extern char *o_alloc(); /* allocate a block of memory */
- extern object *new_inst(); /* make a new instance of a class */
- extern object *new_sinst(); /* an internal (system) version of new_inst*/
- extern object *new_obj(); /* allocate a new object */
- extern object *new_array(); /* make a new array */
- extern object *primitive(); /* perform a primitive operation */
-
- extern object *o_nil; /* current value of pseudo variable nil */
- extern object *o_true; /* current value of pseudo variable true */
- extern object *o_false; /* current value of pseudo variable false */
- extern object *o_smalltalk; /* current value of pseudo var smalltalk */
-
- extern int debug; /* debugging toggle */
-
- /* reference count macro, used during debugging */
- # define rc(x) ((object *)x)->ref_count
-